package com.xingkeduo.business.user.domain;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xingkeduo.business.user.event.FeignException;
import com.xingkeduo.business.user.feign.*;
import com.xingkeduo.pojo.dto.*;
import com.xingkeduo.pojo.enums.SendChannelEnum;
import com.xingkeduo.pojo.utils.ResponseUtils;
import com.xingkeduo.util.pojo.exception.BusinessException;
import com.xingkeduo.util.pojo.exception.DataException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @Description:
 * @Author:gaozifeng
 * @Date 2019/4/28 17:34
 **/
@Component
public class FeignDomain {

    private static Logger log = LoggerFactory.getLogger(FeignDomain.class);

    @Value("${smsOutCode}")
    protected String smsOutCode;
    @Value("${profiles.active}")
    private String active;

    @Resource
    private OperationFeign operationFeign;
    @Resource
    private SendMsgFeign sendMsgFeign;
    @Resource
    private WorkpadFeignService workpadFeignService;
    @Resource
    private MarketingFeignService marketingFeignService;
    @Resource
    private OrderService orderService;

    /**
     * 获取分公司列表
     *
     * @param param:
     * @return : java.util.List<com.xingkeduo.pojo.dto.CompanyDTO>
     * @author : gaozifeng
     * @date : 2019/4/22 19:41
     */
    public List<BaseDTO> getCompanyForList(String param) {
        String company = operationFeign.selectCompany(param);
        JSONObject jsonObject = JSON.parseObject(company);
        List<BaseDTO> baseList = JSONArray.parseArray(jsonObject.getString("data"), BaseDTO.class);
        log.info("获取分公司列表{}baseList.size{}" + baseList.size());
        if (null == baseList || baseList.size() <= 0) {
            throw new BusinessException(BusinessException.Type.DEFAULT, "没有分公司数据");
        }
        return baseList;
    }

    /**
     * 获取门店列表
     *
     * @param param:
     * @return : com.xingkeduo.pojo.dto.CompanyDTO
     * @author : gaozifeng
     * @date : 2019/4/24 10:53
     */
    public List<BaseDTO> getShopForList(String param) {
        String shopList = operationFeign.shoplists(param);
        JSONObject jsonObject = JSON.parseObject(shopList);
        List<BaseDTO> baseList = JSONArray.parseArray(jsonObject.getString("data"), BaseDTO.class);
        log.info("获取门店列表{}baseList.size{}" + baseList.size());
        if (null == baseList || baseList.size() <= 0) {
            throw new BusinessException(BusinessException.Type.DEFAULT, "没有门店列表数据");
        }
        return baseList;
    }

    /**
     * 查询可使用的店铺列表
     *
     * @param :
     * @return : java.util.List<com.xingkeduo.pojo.dto.BaseDTO>
     * @author : gaozifeng
     * @date : 2019/6/1 11:33
     */
    public List<BaseDTO> checkCanShop(String statusList) {
        ResponseUtils<List<BaseDTO>> canShopList = operationFeign.getCanShopList(statusList);
        log.info("请求可用店铺列表" + canShopList.toString());
        if (canShopList.success()) {
            List<BaseDTO> returnList = canShopList.getData();
            return returnList;
        } else {
            log.info("请求可用店铺列表失败");
            throw new BusinessException(BusinessException.Type.DEFAULT, "可用店铺列表请求失败");
        }
    }

    /**
     * 获取门店信息
     *
     * @param param:
     * @return : com.xingkeduo.pojo.dto.CompanyDTO
     * @author : gaozifeng
     * @date : 2019/4/24 10:53
     */
    public BaseDTO getShopByKey(long param) {
        StringBuilder sb = new StringBuilder("{");
        sb.append("id:");
        sb.append(param);
        sb.append("}");
        String shopList = operationFeign.shoplists(sb.toString());
        JSONObject jsonObject = JSON.parseObject(shopList);
        List<BaseDTO> baseList = JSONArray.parseArray(jsonObject.getString("data"), BaseDTO.class);
        log.info("获取门店信息{}baseList.size{}" + baseList.size());
        if (null == baseList || baseList.size() <= 0) {
            throw new BusinessException(BusinessException.Type.DEFAULT, "没有具体门店数据");
        }
        return baseList.get(0);
    }

    /**
     * 根据name查询城市
     *
     * @param name:
     * @return : long
     * @author : gaozifeng
     * @date : 2019/5/6 15:50
     */
    public long selectCity(String name) {
        String country = operationFeign.selectCity(name);
        JSONObject json = JSON.parseObject(country);
        int id = 0;
        if (json.getString("status").equals("1")) {
            System.out.println(json.getString("data"));
            String datas = json.getString("data");
            JSONObject countrTable = JSON.parseObject(datas);
            id = Integer.valueOf(countrTable.getString("id"));
        }
        return id;
    }


    /**
     * 查询店铺服务信息
     *
     * @param shopId:
     * @return : java.lang.String
     * @author : gaozifeng
     * @date : 2019/5/17 10:23
     */
    public List<ShopServiceDTO> getShopServicePriceByShopId(Long shopId) {
        ResponseUtils<BaseDTO> shopServiceDTOResponseUtils = operationFeign.selectShopServiceInfo(shopId);
        if (null == shopServiceDTOResponseUtils) {
            log.info("调用门店服务价格信息失败,请重试");
            throw new BusinessException(BusinessException.Type.DEFAULT, "获取门店服务配置信息失败,请重试");
        }
        BaseDTO data = shopServiceDTOResponseUtils.getData();
        List<ShopServiceDTO> shopsServprodList = data.getShopsServprodList();
        if (null == data || null == shopsServprodList) {
            log.info("该店铺暂未配置服务,请确认!");
            throw new BusinessException(BusinessException.Type.DEFAULT, "该店铺暂未配置服务,请确认!");
        }
        return shopsServprodList;
    }

    /**
     * 查询发型师服务技能
     *
     * @param urlParam:
     * @return : java.lang.String
     * @author : gaozifeng
     * @date : 2019/5/6 15:51
     */
    public List<BaseDTO> selectCraftsmanService(String urlParam) {
        if (null == urlParam) {
            urlParam = "{}";
        }
        String serviceList = operationFeign.servprodLists(urlParam);
        JSONObject jsonObject = JSON.parseObject(serviceList);
        List<BaseDTO> returnList;
        if (jsonObject.getString("status").equals("1")) {
            System.out.println(jsonObject.getString("data"));
            String datas = jsonObject.getString("data");
            returnList = JSON.parseArray(datas, BaseDTO.class);
            return returnList;
        } else {
            return new ArrayList<>();
        }
    }

    /**
     * 小程序授权code
     *
     * @param js_code:
     * @param mobile_type:
     * @return : java.lang.String
     * @author : gaozifeng
     * @date : 2019/5/8 12:51
     */
    public WxMaCodeDTO consumerCode(String js_code, String mobile_type) {
        String code = sendMsgFeign.code(js_code, mobile_type);
        log.info("小程序拉取用户信息---------code-----" + code);
        WxMaCodeDTO wxMaCodeDTO = JSON.parseObject(code, WxMaCodeDTO.class);
        log.info("小程序拉取用户信息---------wxMaCodeDTO-----" + wxMaCodeDTO);
        return wxMaCodeDTO;
    }


    /**
     * 小程序拉取用户信息
     *
     * @param sessionKey:
     * @param encryptedData:
     * @param iv:
     * @return : com.xingkeduo.pojo.dto.WxMaCodeDTO
     * @author : gaozifeng
     * @date : 2019/5/9 14:08
     */
    public WxMaUserInfo getUserInfo(String sessionKey, String encryptedData, String iv) {
        log.info("user  小程序 拉取用户信息  getUserInfo-----sessionKey[{}],encryptedData[{}],iv[{}],", sessionKey, encryptedData, iv);
        WxEncryDTO wxEncryDTO = new WxEncryDTO();
        wxEncryDTO.setEncryptedData(encryptedData);
        wxEncryDTO.setSessionKey(sessionKey);
        wxEncryDTO.setIv(iv);
        String user_info = sendMsgFeign.get_user_info(wxEncryDTO);
        log.info("获取小程序的user_info-----------------------" + user_info);
        WxMaUserInfo wxMaUserInfo = JSON.parseObject(user_info, WxMaUserInfo.class);
        log.info("转换小程序userInfo-----------------------" + user_info);
        return wxMaUserInfo;
    }

    /**
     * 发送验证码
     * 先固定，以后新增可以对channel，轮询等
     *
     * @param phone:
     * @param random:
     * @return : void
     * @author : gaozifeng
     * @date : 2019/5/9 16:19
     */
    public void sendMsg(int type, String phone, String random) {
        SendBaseDto sendBaseDto = new SendBaseDto();
        sendBaseDto.setChannel(SendChannelEnum.ALI.getType());
        sendBaseDto.setType(type);
        sendBaseDto.setPhone(phone);
        sendBaseDto.setSmsCode(random);
        sendBaseDto.setOutCode(smsOutCode);
        log.info("user 发送手机短信，type[{}],phone[{}],", type, phone);
        sendMsgFeign.send(sendBaseDto);
    }

    /**
     * 校验失败,发送端失败,本端不再校验
     *
     * @param phone:
     * @param verfyCode:
     * @return : void
     * @author : gaozifeng
     * @date : 2019/5/9 16:28
     */
    public void checkMsg(int type, String phone, String verfyCode) {
        log.info("user 校验手机短信，type[{}],phone[{}],", type, phone);
        SendBaseDto sendBaseDto = new SendBaseDto();
        sendBaseDto.setType(type);
        sendBaseDto.setOutCode(smsOutCode);
        sendBaseDto.setPhone(phone);
        sendBaseDto.setSmsCode(verfyCode);
        sendBaseDto.setChannel(SendChannelEnum.ALI.getType());
        String returnMsg = sendMsgFeign.checkPhoneAndMsg(sendBaseDto);
        ResponseDto msgDto = JSON.parseObject(returnMsg, ResponseDto.class);
        if (!("SUCCESS").equals(msgDto.getData())) {
            log.info("校验短信 缓存获取失败,发短信端失败");
            throw new DataException(DataException.Type.DEFAULT, "验证码发送失败.");
        }
    }


    /**
     * 拿code，拉取用户信息
     *
     * @param code:
     * @return : com.xingkeduo.pojo.dto.AlipayUserDTO
     * @author : gaozifeng
     * @date : 2019/5/10 18:56
     */
    public AlipayUserDTO getAliUserInfo(String code) {
        ResponseUtils<AlipayUserDTO> aliUserInfo = sendMsgFeign.getAliUserInfo(code);
        if (!aliUserInfo.success()) {
            throw new DataException(DataException.Type.DEFAULT, "阿里授权失败");
        }
        log.info("阿里code获取用户信息-------------" + aliUserInfo.getData());
        AlipayUserDTO data = aliUserInfo.getData();
        return data;
    }


    /**
     * 获取公众号code
     *
     * @param mpId:
     * @param code:
     * @return : com.xingkeduo.pojo.dto.WxMpOAuth2AccessToken
     * @author : gaozifeng
     * @date : 2019/5/16 17:48
     */
    public WxMpOAuth2AccessToken getWechatCode(String mpId, String code) {
        ResponseUtils<WxMpOAuth2AccessToken> verify = sendMsgFeign.verify(mpId, code);
//        {"msg":"success","timestamp":1558001798438,"data":{"accessToken":"21_B9XY5OhvZHm-V0BCvUHxUtYwh0fCfnTWd2FP33z1G0Fl1qZd-aMrlDQ3kEhtZ8cGl9C5PHrWWIRFbvmA2F5wPg","expiresIn":7200,"refreshToken":"21_19BG913KvB4qMBKmqyN03aYeidCE73ySgpvDkYzVTU4p20igqtXf2X9jye2nJ8ZGca10kFhJuTFkTPXS_45W_g","openId":"oCKsY5zt5-7JH6aNn73miRxur9pA","scope":"snsapi_userinfo"},"status":1}
        if (!verify.success()) {
            log.info("授权失败情况：" + verify.getMsg());
            throw new DataException(DataException.Type.DEFAULT, "微信公众号授权失败");
        }

        WxMpOAuth2AccessToken wxMpOAuth2AccessToken = verify.getData();
        if (null == wxMpOAuth2AccessToken || null == wxMpOAuth2AccessToken.getOpenId()) {
            log.info("wxMpOAuth2AccessToken-----失败-----" + wxMpOAuth2AccessToken.toString());
            throw new DataException(DataException.Type.DEFAULT, "授权转换失败");
        } else {
            log.info("wxMpOAuth2AccessToken-成功---------" + wxMpOAuth2AccessToken.toString());
            return wxMpOAuth2AccessToken;
        }
    }

    /**
     * 获取用户授权
     *
     * @param mpId:
     * @param accessToken:
     * @param openId:
     * @return : com.xingkeduo.pojo.dto.SubscribeDTO
     * @author : gaozifeng
     * @date : 2019/5/16 17:57
     */
    public SubscribeDTO getWechatUserInfo(String mpId, String accessToken, String openId) {
        ResponseUtils<SubscribeDTO> getuserinfo = sendMsgFeign.getuserinfo(mpId, accessToken, openId);
        if (!getuserinfo.success()) {
            log.info("user公众号拉取用户信息失败-------" + getuserinfo.getMsg());
            throw new DataException(DataException.Type.DEFAULT, "微信公众号获取用户信息失败");
        }
        SubscribeDTO subscribeDTO = getuserinfo.getData();
        if (null == subscribeDTO || null == subscribeDTO.getOpenId()) {
            log.info("subscribeDTO-失败---------" + subscribeDTO.toString());
            throw new DataException(DataException.Type.DEFAULT, "subscribeDTO-失败");
        } else {
            log.info("subscribeDTO-成功---------" + subscribeDTO.toString());
            return subscribeDTO;
        }
    }

    /**
     * 用户30天未理发 调用
     *
     * @return : com.xingkeduo.pojo.utils.ResponseUtils<java.lang.Boolean>
     * @author : gaozifeng
     * @date : 2019/6/5 11:49
     */
    public Boolean consumerPushHair(List<WxMaUserInfo> wxMaUserInfos) {
        ResponseUtils<Boolean> booleanResponseUtils = sendMsgFeign.pushHaircutReminderMessage(wxMaUserInfos);
        log.info("用户30天未理发 消息推送，，user ---消息返回-" + JSON.toJSONString(booleanResponseUtils));
        if (!booleanResponseUtils.success()) {
            log.info("用户30天未理发 消息推送，，user ---消息失败返回-" + booleanResponseUtils.getMsg());
            return false;
        } else {
            return true;
        }
    }


    /**
     * 发型师服务，价格，生效/失效 更改
     *
     * @param staffId:
     * @return : java.lang.String
     * @author : gaozifeng
     * @date : 2019/6/12 10:34
     */
    public void receiveStaffId(Long staffId) {
        log.info("发型师服务通知id为[{}]---", staffId);
        ResponseMessage responseMessage = workpadFeignService.receiveStaffId(staffId);
        if (1 != responseMessage.getStatus() || responseMessage.getCode() != 200) {
            log.info("发型师服务通知失败id为[{}],消息是[{}],", staffId, responseMessage.getMsg());
            throw new DataException(DataException.Type.DEFAULT, "发型师服务更改通知失败");
        }
    }

    /**
     * 根据shopid 获取城市id
     *
     * @param shopId:
     * @return : long
     * @author : gaozifeng
     * @date : 2019/6/20 10:36
     */
    public long getCityId(long shopId) {
        log.info("根据店铺id 获取城市id,shopId[{}]---", shopId);
        ResponseUtils<Long> cityInfo = operationFeign.getCityId(shopId);
        log.info("返回城市信息cityInfo[{}]---", cityInfo);
        if (!cityInfo.success()) {
            throw new DataException(DataException.Type.DEFAULT, "店铺获取城市失败");
        }
        Long cityId = cityInfo.getData();
        if (0L == cityId) {
            throw new DataException(DataException.Type.NULL, "城市");
        }
        return cityId;
    }

    /**
     * 发型师联系用户
     *
     * @param pnpLogDTO:
     * @return : java.lang.String
     * @author : gaozifeng
     * @date : 2019/6/20 10:47
     */
    public String callUserPhone(PnpLogDTO pnpLogDTO) {
        log.info("发型师联系用户,DTO[{}]---", pnpLogDTO);
        ResponseUtils<String> stringResponseUtils = sendMsgFeign.callUserPhone(pnpLogDTO);
        log.info("发型师联系用户,返回参数[{}]---", stringResponseUtils);
        if (!stringResponseUtils.success()) {
            throw new DataException(DataException.Type.DEFAULT, "获取手机号失败");
        }
        String virtualPhone = stringResponseUtils.getData();
        if (StringUtils.isEmpty(virtualPhone)) {
            throw new DataException(DataException.Type.NULL, "手机号");
        }
        if (virtualPhone.length() < 13) {
            throw new DataException(DataException.Type.DEFAULT, "获取手机号为空");
        }
        return virtualPhone;
    }

    /**
     * 新用户领5折券
     *
     * @param userId:
     * @return : java.lang.String
     * @author : gaozifeng
     * @date : 2019/7/12 10:18
     */
    public Map bindReceiveAccountOfShareNewUser(Long userId) {
        ResponseMessage responseMessage = marketingFeignService.bindReceiveAccountOfShareNewUser(userId);
        log.info("新用户用户领券信息：" + responseMessage == null ? "" : (responseMessage.getData() == null ? "" : responseMessage.getData().toString()));
        if (responseMessage.getStatus() == 1 && responseMessage.getData() != null && StringUtils.isNotEmpty(responseMessage.getData().toString())) {
            Map mapTypes = (Map) responseMessage.getData();
            log.info("新用户用户领券信息Map[{}]", mapTypes.toString());
            if (mapTypes.containsKey("id") && mapTypes.containsKey("marketingType")) {
                return mapTypes;
            }
            throw new DataException(DataException.Type.NULL, "领取记录不能");
        } else {
            throw new DataException(DataException.Type.DEFAULT, responseMessage.getMsg());
        }
    }

    /**
     * 新用户下单 老用户补发5折券
     *
     * @param userId:
     * @return : java.lang.String
     * @author : gaozifeng
     * @date : 2019/7/12 10:18
     */
    public Map bindReceiveAccountOfShareOldUser(Long userId) {
        ResponseMessage responseMessage = marketingFeignService.bindReceiveAccountOfShareOldUser(userId);
        log.info("老用户领券信息：" + responseMessage == null ? "" : (responseMessage.getData() == null ? "" : responseMessage.getData().toString()));
        if (responseMessage.getStatus() == 1 && responseMessage.getData() != null && StringUtils.isNotEmpty(responseMessage.getData().toString())) {
            Map mapTypes = (Map) responseMessage.getData();
            log.info("老用户领券信息Map[{}]", mapTypes.toString());
            if (mapTypes.containsKey("id") && mapTypes.containsKey("marketingType")) {
                return mapTypes;
            }
        } else {
            log.info("老用户领券信息Map失败原因[{}]", responseMessage.getMsg());
            throw new DataException(DataException.Type.DEFAULT, responseMessage.getMsg());
        }
        return null;
    }

    /**
     * 查询用户上一次服务信息
     *
     * @param userIds:
     * @return : java.lang.String
     * @author : gaozifeng
     * @date : 2019/7/16 10:22
     */
    public OrderCraftsmanResponseDTO queryServices(String userIds) {
        log.info("查询用户[{}]上一次订单服务信息", userIds);
        ResponseUtils<OrderUserResponseDto> respOrderDTO = null;
        try {
            respOrderDTO = orderService.queryServices(userIds);
        } catch (Throwable t) {
            FeignException.feignExceptionHandle(t);
        }
        if (respOrderDTO.success()) {
            OrderUserResponseDto orderDTO = respOrderDTO.getData();
            log.info("用户上一次服务信息[{}]", JSON.toJSONString(orderDTO));

            OrderCraftsmanResponseDTO dto = new OrderCraftsmanResponseDTO();
            dto.setId(orderDTO.getId())
                    .setOrderNo(Optional.ofNullable(orderDTO.getOrderNo()).orElse(""))
                    .setConsumerId(Optional.ofNullable(orderDTO.getUserId()).orElse(""))
                    .setCraftsmanId(Optional.ofNullable(orderDTO.getAdminId()).orElse("0"))
                    .setShopId(Optional.ofNullable(orderDTO.getStoreId()).orElse("0"));
            return dto;
        } else {
            log.info("远程调用失败msg[{}]", respOrderDTO.getMsg());
            throw new DataException(DataException.Type.DEFAULT, respOrderDTO.getMsg());
        }
    }

//    //测试
//    public void testFescar(VendorTable vendorTable) throws Throwable {
//        operationFeign.insertVendor(vendorTable);
//    }
}
